/**
 * 
 */
package edu.cmu.aes.project1.app3;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQResultSequence;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * @author swasanta
 * 
 */
public class HTMLTransformation {

	private static final String TARGET_PATH = "output/app3/";
	private static final String ORIGINAL_PATH = "edu/cmu/aes/project1/app3/";
	private static final String SCRIPT_FILE = "jquery-1.6.4.min.js";
	private static final String CSS_FILE = "app3.css";

	public static void main(String[] args) {

		DOMSource domsource = parseXML("output/app2/consolidated_data.xml");

		transform(domsource,true);

	}

	private static Element convertDataType(Document document, Node sourceNode) {
		NodeList nodeList = sourceNode.getChildNodes();
		Element element = document.createElement(sourceNode.getNodeName());
		boolean isTextNode = false;
		if (nodeList.getLength() == 1) {
			// element = document.createElement(sourceNode.getNodeName());
			Node firstChild = nodeList.item(0);
			if (firstChild.getNodeType() == Node.TEXT_NODE) {
				element.setTextContent(sourceNode.getTextContent());
				isTextNode = true;
			}
		}
			if(!isTextNode){
				// element = document.createElement(sourceNode.getNodeName());
				for (int i = 0; i < nodeList.getLength(); i++) {
					Node child = nodeList.item(i);
					Element childElement = convertDataType(document, child);
					element.appendChild(childElement);
				}
			}

		NamedNodeMap oldMap = sourceNode.getAttributes();
		for (int i = 0; i < oldMap.getLength(); i++) {
			Node attributeNode = oldMap.item(i);
			element.setAttribute(attributeNode.getNodeName(),
					attributeNode.getNodeValue());
		}

		return element;
	}

	public static void transform(XQResultSequence result, boolean isDetail, String strAttr) {
		DOMSource domSource = null;
		try {
			// System.out.println(result.getItem().getNode());
			
			DocumentBuilderFactory builderFactory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder builder = builderFactory.newDocumentBuilder();
			Document document = builder.newDocument();
			Element root = document.createElement("models");
			Element startPiont = root;
			if(isDetail){
				Element model = document.createElement("model");
				model.setAttribute("name", strAttr);
				root.appendChild(model);
				startPiont = model;
			}else{
				root.setAttribute("sortBy", strAttr);
			}
			while(result.next()){
				Node node = result.getNode(); 
				Element child = convertDataType(document, node);
				startPiont.appendChild(child);
			}

			domSource = new DOMSource(root);

		} catch (XQException e1) {
			e1.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (TransformerFactoryConfigurationError e) {
			e.printStackTrace();
		}

//		 System.out.println("Start tranforming");
//		 prepareFolder();
//		 try {
//		
//		 TransformerFactory tFactory = TransformerFactory.newInstance();
//		
//		 Transformer transformer = tFactory.newTransformer();
//		
//		 transformer.transform(domSource,
//					new javax.xml.transform.stream.StreamResult(
//							new FileOutputStream("test.xml")));
//		
//		 System.out.println("Transfomation is finished");
//		 } catch (Exception e) {
//			 e.printStackTrace();
//		 }
		transform(domSource, isDetail);

	}

	public static void transform(DOMSource domsource, boolean isDetail) {
		System.out.println("Start tranforming");
		prepareFolder();
		try {
			
			String xslFile;
			String outputFile;
			if(isDetail){
				xslFile = "edu/cmu/aes/project1/app3/detail.xsl";
				outputFile = "output/app3/detail.html";
			}else {
				xslFile = "edu/cmu/aes/project1/app3/index.xsl";
				outputFile = "output/app3/index.html";
			}
			
			System.setProperty("javax.xml.transform.TransformerFactory", "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
			
			InputStream xslStream = ClassLoader
					.getSystemResourceAsStream(xslFile);

			TransformerFactory tFactory = TransformerFactory.newInstance();

			Transformer transformer = tFactory
					.newTransformer(new javax.xml.transform.stream.StreamSource(
							xslStream));

			transformer.transform(domsource,
					new javax.xml.transform.stream.StreamResult(
							new FileOutputStream(outputFile)));

			System.out.println("Transfomation is finished");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static void prepareFolder() {
		File fileDirectory = new File(TARGET_PATH);
		if (!fileDirectory.exists())
			fileDirectory.mkdirs();

//		File scriptFile = new File(TARGET_PATH + SCRIPT_FILE);
//		if (!scriptFile.exists()) {
//			scriptFile.delete();
//		}
//		copyFile(ORIGINAL_PATH, TARGET_PATH, SCRIPT_FILE);

		File cssFile = new File(TARGET_PATH + CSS_FILE);
		if (!cssFile.exists()) {
			cssFile.delete();
		}
		copyFile(ORIGINAL_PATH, TARGET_PATH, CSS_FILE);
	}

	private static void copyFile(String ordPath, String desPath, String fileName) {
		InputStream inputFile = ClassLoader.getSystemResourceAsStream(ordPath
				+ fileName);
		File outputFile = new File(desPath + fileName);

		FileWriter out = null;

		try {
			out = new FileWriter(outputFile);
			int c;

			while ((c = inputFile.read()) != -1)
				out.write(c);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (inputFile != null) {
				try {
					inputFile.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (out != null) {
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public static DOMSource parseXML(String fileName) {
		DocumentBuilderFactory builderFactory = DocumentBuilderFactory
				.newInstance();

		try {
			File file = new File(fileName);
			InputStream xmlStream = new FileInputStream(file);
			builderFactory.setNamespaceAware(true); // never forget this!
			DocumentBuilder builder = builderFactory.newDocumentBuilder();
			Document document = builder.parse(xmlStream);

			return new DOMSource(document.getFirstChild());
			// }

		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return new DOMSource();
	}
}
